home *** CD-ROM | disk | FTP | other *** search
/ Joystick Magazine 1995 July & August / cd No4 joystick No62.iso / mac / pc / EMULATOR / PC64 / LINKASM.ASM < prev    next >
Assembly Source File  |  1994-03-08  |  14KB  |  427 lines

  1. ;Datenblîcke zwischen PC und C64 Åbertragen
  2.  
  3. CSYNC     equ 2                         ;Kontaktaufnahme und Synchronisation
  4. CREADY    equ 3                         ;Synchronisation erfolgreich
  5. CSEND     equ 4                         ;PC will senden
  6. CRECEIVE  equ 5                         ;PC will empfangen
  7. CDATALO   equ 6                         ;EmpfangsbestÑtigung Low-Nibble
  8. CDATAHI   equ 7                         ;EmpfangsbestÑtigung High-Nibble
  9. COK       equ 9                         ;PrÅfsumme in Ordnung
  10.  
  11. ETIMEOUT  equ -1                        ;Fremdrechner antwortet nicht
  12. ETRANSFER equ -2                        ;öbertragungsfehler aufgetreten
  13.  
  14. .model large,c
  15. .data
  16.  
  17. L64Result dw ETIMEOUT                   ;Letzter RÅckgabewert
  18.   public L64Result
  19. L64State db 4 dup (255)                 ;ZustÑnde von BUSY/PA2 in Bit 7
  20.   public L64State                       ;255 = nicht angesprochen oder Fehler
  21. L64LinkWaits db 4 dup (0)               ;FÅr langsame Schnittstellen (0 bis 127)
  22.   public L64LinkWaits
  23. L64JoyWaits db 4 dup (0)                ;FÅr langsame Schnittstellen (0 bis 127)
  24.   public L64JoyWaits
  25.  
  26. .code
  27.  
  28. ;Gleichzeitig 4 Bits einlesen und ausgeben
  29. ;Eingabe: AH = Auszugebender Wert in den Bits 0 bis 3, Bit 7 = 0
  30. ;         CL = Letzter Zustand von BUSY/PA2 in Bit 7, Rest 0
  31. ;         DX = Portadresse der parallelen Schnittstelle
  32. ;         DS = 0
  33. ;Ausgabe: AH = Eingelesener Wert in den Bits 3 bis 6, Rest 0
  34. ;         CL = Neuer Zustand von BUSY/PA2 in Bit 7, Rest 0
  35. ;         CF = Timeout-Fehler aufgetreten
  36. ;éndert:  AL,CH
  37.  
  38. Transfer proc near
  39.   or AH,01110000b                       ;Spitzen am Joystick vermeiden
  40.   mov CH,DS:[046Ch]                     ;1/18 bis 2/18 Sekunden Timeout
  41.   add CH,2
  42.   inc DX                                ;Parallelen Statusport lesen
  43. @@Wait:
  44.   cmp CH,DS:[046Ch]                     ;Zeit abgelaufen?
  45.   js @@Timeout
  46.   in AL,DX                              ;Hat sich das Busy-Bit geÑndert?
  47.   xor AL,CL
  48.   jns @@Wait
  49.   mov CH,0                              ;ZÑhler fÅr Wartezyklen laden
  50. TransferWaits equ byte ptr $-1
  51. @@Delay:
  52.   in AL,DX                              ;Daten nochmal lesen
  53.   dec CH
  54.   jns @@Delay
  55.   dec DX                                ;BestÑtigung abschicken
  56.   xchg AL,AH
  57.   out DX,AL
  58.   and AH,01111000b                      ;Unrelevante Bits ausblenden
  59.   xor CL,10000000b                      ;Neuen Busy-Status sichern
  60.   or AL,10000000b                       ;Flankentrigger zurÅcksetzen
  61.   out DX,AL
  62.   ret                                   ;Mit gelîschtem CF zurÅck
  63. @@Timeout:
  64.   dec DX                                ;Auf Datenport zurÅckschalten
  65.   stc                                   ;Timeout-Fehler zurÅckgeben
  66.   ret
  67. Transfer endp
  68.  
  69. ;PC und C64 synchronisieren
  70. ;Eingabe: DX = Portadresse parallele Schnittstelle
  71. ;         DS:046C = ZÑhler fÅr Systemuhr 18 mal pro Sekunde
  72. ;Ausgabe: CL = Neuer Status von BUSY/PA2 in Bit 8, Rest 0
  73. ;         CF = Timeout-Fehler aufgetreten
  74. ;éndert:  AX,BX,CH
  75.  
  76. Sync proc near
  77.   mov AL,CSYNC or 10000000b             ;Flankentrigger initialisieren
  78.   out DX,AL
  79.   inc DX                                ;Zustand von BUSY/PA2 holen
  80.   in AL,DX
  81.   and AL,10000000b
  82.   mov CL,AL
  83.   dec DX
  84.   xor CL,10000000b                      ;Beim ersten Mal nicht warten
  85. @@Reset:
  86.   mov BX,5                              ;FÅnf DurchlÑufe sind nîtig
  87. @@Next:
  88.   mov AH,CSYNC                          ;Auf Reaktion warten
  89.   call Transfer
  90.   jc @@Timeout
  91.   cmp AH,CSYNC shl 3                    ;Alles au·er SYNC ignorieren
  92.   jne @@Reset
  93.   dec BX                                ;Kamen 5 SYNCs hintereinander?
  94.   jne @@Next
  95.   mov AH,CREADY                         ;Synchronisation abschlie·en
  96.   call Transfer
  97.   jc @@Timeout
  98.   cmp AH,CSYNC shl 3                    ;BestÑtigung ÅberprÅfen
  99.   jne @@Reset
  100. @@Timeout:
  101.   ret
  102. Sync endp
  103.  
  104. ;Byte ausgeben
  105. ;Eingabe: AH = auszugebender Wert
  106. ;         CL = Letzter Status von BUSY/PA2 in Bit 8, Rest 0
  107. ;         DX = Portadresse parallele Schnittstelle
  108. ;         DS = 0
  109. ;Ausgabe: CL = Neuer Status von BUSY/PA2 in Bit 8, Rest 0
  110. ;         CF = Fehler aufgetreten
  111. ;éndert:  AX,CH
  112.  
  113. PutByte proc near
  114.   mov CS:PutSave,AH                     ;Wert fÅr spÑter retten
  115.   and AH,00001111b                      ;Unteres Halbbyte ausgeben
  116.   call Transfer
  117.   jc @@Timeout
  118.   cmp AH,CDATALO shl 3                  ;BestÑtigung ÅberprÅfen
  119.   jne @@Error
  120.   mov AH,-1                             ;Wert zurÅckholen
  121. PutSave equ byte ptr $-1                ;Selbstmodifizierender Code
  122.   shr AH,1                              ;Oberes Halbbyte ausgeben
  123.   shr AH,1
  124.   shr AH,1
  125.   shr AH,1
  126.   call Transfer
  127.   jc @@Timeout
  128.   cmp AH,CDATAHI shl 3                  ;BestÑtigung ÅberprÅfen
  129.   jne @@Error
  130.   ret                                   ;Mit gelîschtem CF zurÅck
  131. @@Error:
  132.   stc                                   ;Fehler zurÅckgeben
  133. @@Timeout:
  134.   ret
  135. PutByte endp
  136.  
  137. ;Byte einlesen
  138. ;Eingabe: CL = Letzter Status von BUSY/PA2 in Bit 8, Rest 0
  139. ;         DX = Portadresse parallele Schnittstelle
  140. ;         DS = 0
  141. ;Ausgabe: AH = Eingelesener Wert
  142. ;         CL = Neuer Status von BUSY/PA2 in Bit 8, Rest 0
  143. ;         CF = Fehler aufgetreten
  144. ;éndert:  AL,CH
  145.  
  146. GetByte proc near
  147.   mov AH,CDATAHI                        ;Unteres Halbbyte einlesen
  148.   call Transfer
  149.   jc @@Timeout
  150.   shr AH,1
  151.   shr AH,1
  152.   shr AH,1
  153.   mov CS:GetSave,AH                     ;Wert fÅr spÑter sichern
  154.   mov AH,CDATALO                        ;Oberes Halbbyte einlesen
  155.   call Transfer
  156.   jc @@Timeout
  157.   shl AH,1                              ;Halbbytes miteinander verknÅpfen
  158.   or AH,-1
  159. GetSave equ byte ptr $-1                ;Selbstmodifizierender Code
  160. @@Timeout:
  161.   ret
  162. GetByte endp
  163.  
  164. ;Datenblock an den C64 senden
  165. L64Send proc uses SI DI,wLpt:word,lpBuffer:dword,iCount:word
  166.   public L64Send
  167.   mov BX,wLpt                           ;Status von BUSY/PA2 holen
  168.   mov CL,L64State[BX]
  169.   mov AL,L64LinkWaits[BX]               ;Wartezyklen Åbertragen
  170.   mov CS:TransferWaits,AL
  171.   push DS                               ;Zugriff auf BIOS-Variablen
  172.   xor DX,DX
  173.   mov DS,DX
  174.   shl BX,1                              ;Portadresse holen
  175.   mov DX,DS:[0408h+BX]
  176.   cmp DX,0100h                          ;Schnittstelle vorhanden?
  177.   jb @@Timeout
  178.   test DX,0003h
  179.   jne @@Timeout
  180.   cmp CL,255                            ;Trat letztes Mal ein Fehler auf?
  181.   je @@Reset
  182. @@SyncOk:
  183.   mov AH,CSEND                          ;Auf empfangsbereiten C64 prÅfen
  184.   call Transfer
  185.   jc @@Timeout
  186.   cmp AH,CREADY shl 3
  187.   jne @@Error
  188.   mov BX,iCount                         ;LÑnge des Datenblocks senden
  189.   mov AH,BL
  190.   call PutByte
  191.   jc @@Error
  192.   mov AH,BH
  193.   call PutByte
  194.   jc @@Error
  195.   xor SI,SI                             ;PrÅfsumme initialisieren
  196.   and BX,BX                             ;Sind Daten vorhanden?
  197.   je @@Ready
  198.   les DI,lpBuffer                       ;Pufferadresse holen
  199. @@Next:
  200.   mov AL,ES:[DI]                        ;PrÅfsumme aktualisieren
  201.   add SI,AX
  202.   mov AH,AL                             ;Byte ausgeben
  203.   call PutByte
  204.   jc @@Error
  205.   inc DI                                ;NÑchstes Byte behandeln
  206.   dec BX
  207.   jne @@Next
  208. @@Ready:
  209.   mov AX,SI                             ;PrÅfsumme Åbermitteln
  210.   mov AH,AL
  211.   call PutByte
  212.   jc @@Error
  213.   mov AH,CREADY                         ;Auf BestÑtigung der PrÅfsumme warten
  214.   call Transfer
  215.   jc @@Error
  216.   cmp AH,COK shl 3
  217.   jne @@Error
  218.   mov AX,iCount                         ;Alles in Ordnung
  219. @@Return:
  220.   pop DS                                ;Zustand von BUSY/PA2 sichern
  221.   mov BX,wLpt
  222.   mov L64State[BX],CL
  223.   mov L64Result,AX                      ;RÅckgabewert speichern
  224.   ret
  225. @@Reset:
  226.   call Sync                             ;Neue Synchronisation durchfÅhren
  227.   jnc @@SyncOk
  228.   mov CL,255
  229. @@Timeout:
  230.   mov AX,ETIMEOUT                       ;C64 ist beschÑftigt
  231.   jmp @@Return
  232. @@Error:
  233.   mov CL,255                            ;Neusynchronisation nîtig
  234.   mov AX,ETRANSFER                      ;öbertragungsfehler zurÅckgeben
  235.   jmp @@Return
  236. L64Send endp
  237.  
  238. ;Datenblock vom C64 empfangen
  239. L64Receive proc uses SI DI,wLpt:word,lpBuffer:dword,iCount:word
  240.   public L64Receive
  241.   mov BX,wLpt                           ;Status von BUSY/PA2 holen
  242.   mov CL,L64State[BX]
  243.   mov AL,L64LinkWaits[BX]               ;Wartezyklen Åbertragen
  244.   mov CS:TransferWaits,AL
  245.   push DS                               ;Zugriff auf BIOS-Variablen
  246.   xor DX,DX
  247.   mov DS,DX
  248.   shl BX,1                              ;Portadresse holen
  249.   mov DX,DS:[0408h+BX]
  250.   cmp DX,0100h                          ;Schnittstelle vorhanden?
  251.   jb @@Timeout
  252.   test DX,0003h
  253.   jne @@Timeout
  254.   cmp CL,255                            ;Trat letztes Mal ein Fehler auf?
  255.   je @@Reset
  256. @@SyncOk:
  257.   mov AH,CRECEIVE                       ;Auf sendebereiten C64 prÅfen
  258.   call Transfer
  259.   jc @@Timeout
  260.   cmp AH,CREADY shl 3
  261.   jne @@Error
  262.   call GetByte                          ;LÑnge des Datenblocks empfangen
  263.   jc @@Error
  264.   mov BL,AH
  265.   call GetByte
  266.   jc @@Error
  267.   mov BH,AH
  268.   cmp BX,iCount                         ;Mit Puffergrî·e vergleichen
  269.   ja @@Error
  270.   mov iCount,BX                         ;LÑnge fÅr spÑter sichern
  271.   xor SI,SI                             ;PrÅfsumme initialisieren
  272.   and BX,BX                             ;Sind Daten vorhanden?
  273.   je @@Ready
  274.   les DI,lpBuffer                       ;Pufferadresse holen
  275.   clc
  276. @@Next:
  277.   call GetByte                          ;Byte einlesen
  278.   jc @@Error
  279.   mov AL,AH
  280.   stosb
  281.   add SI,AX                             ;PrÅfsumme aktualisieren
  282.   dec BX                                ;NÑchstes Byte behandeln
  283.   jne @@Next
  284. @@Ready:
  285.   call GetByte                          ;PrÅfsumme holen
  286.   jc @@Error
  287.   mov BX,SI                             ;und vergleichen
  288.   cmp AH,BL
  289.   jne @@Error
  290.   mov AH,CREADY                         ;Korrekte PrÅfsumme bestÑtigen
  291.   call Transfer
  292.   jc @@Error
  293.   cmp AH,COK shl 3
  294.   jne @@Error
  295.   mov AX,iCount                         ;Alles in Ordnung
  296. @@Return:
  297.   pop DS                                ;Zustand von BUSY/PA2 sichern
  298.   mov BX,wLpt
  299.   mov L64State[BX],CL
  300.   mov L64Result,AX                      ;RÅckgabewert speichern
  301.   ret
  302. @@Reset:
  303.   call Sync                             ;Neue Synchronisation durchfÅhren
  304.   jnc @@SyncOk
  305.   mov CL,255
  306. @@Timeout:
  307.   mov AX,ETIMEOUT                       ;C64 ist beschÑftigt
  308.   jmp @@Return
  309. @@Error:
  310.   mov CL,255                            ;Neusynchronisation nîtig
  311.   mov AX,ETRANSFER                      ;öbertragungsfehler zurÅckgeben
  312.   jmp @@Return
  313. L64Receive endp
  314.  
  315. ;Stellung des Joysticks abfragen
  316. L64Joystick proc wLpt:word
  317.   public L64Joystick
  318.   mov BX,wLpt                           ;Wartezyklen holen
  319.   mov CH,L64JoyWaits[BX]
  320.   push DS                               ;Zugriff auf BIOS-Variablen
  321.   xor AX,AX
  322.   mov DS,AX
  323.   shl BX,1                              ;Portadresse holen
  324.   mov DX,DS:[0408h+BX]
  325.   cmp DX,0100h                          ;Schnittstelle vorhanden?
  326.   jb @@Error
  327.   test DX,0003h
  328.   jne @@Error
  329.   in AL,DX                              ;Links/Rechts/Feuer zurÅcksetzen
  330.   or AL,01110000b
  331.   mov AH,AL
  332.   and AL,10111111b                      ;Feuer abfragen
  333.   out DX,AL
  334.   add DL,2                              ;Oben/Unten zurÅcksetzen
  335.   mov AL,00000000b
  336.   out DX,AL
  337.   mov CL,CH
  338. @@Delay0:
  339.   in AL,DX                              ;Feuer-Bit holen
  340.   dec CL
  341.   jns @@Delay0
  342.   mov BL,AL
  343.   sub DL,2                              ;Rechts abfragen
  344.   mov AL,AH
  345.   and AL,11011111b
  346.   out DX,AL
  347.   add DL,2
  348.   mov CL,CH
  349. @@Delay1:
  350.   in AL,DX                              ;Rechts-Bit holen
  351.   dec CL
  352.   jns @@Delay1
  353.   shr AL,1
  354.   rcl BL,1
  355.   sub DL,2                              ;Links abfragen
  356.   mov AL,AH
  357.   and AL,11101111b
  358.   out DX,AL
  359.   add DL,2
  360.   mov CL,CH
  361. @@Delay2:
  362.   in AL,DX                              ;Links-Bit holen
  363.   dec CL
  364.   jns @@Delay2
  365.   shr AL,1
  366.   rcl BL,1
  367.   sub DL,2                              ;Links/Rechts/Feuer zurÅcksetzen
  368.   mov AL,AH
  369.   out DX,AL
  370.   add DL,2                              ;Unten abfragen
  371.   mov AL,00001000b
  372.   out DX,AL
  373.   mov CL,CH
  374. @@Delay3:
  375.   in AL,DX                              ;Unten-Bit holen
  376.   dec CL
  377.   jns @@Delay3
  378.   shr AL,1
  379.   rcl BL,1
  380.   mov AL,00000010b                      ;Oben abfragen
  381.   out DX,AL
  382. @@Delay4:
  383.   in AL,DX                              ;Oben-Bit holen
  384.   dec CH
  385.   jns @@Delay4
  386.   shr AL,1
  387.   rcl BL,1
  388.   mov AL,00000000b                      ;Oben/Unten zurÅcksetzen
  389.   out DX,AL
  390.   mov AX,BX                             ;Ergebnis zurÅckliefern
  391.   and AX,0000000000011111b
  392. @@Error:
  393.   pop DS                                ;Ergebnisvariable setzen
  394.   mov L64Result,AX
  395.   ret
  396. L64Joystick endp
  397.  
  398. ;Stellung des alternativen Joysticks abfragen
  399. L64Joystick2 proc wLpt:word
  400.   public L64Joystick2
  401.   push DS                               ;Zugriff auf BIOS-Variablen
  402.   xor AX,AX
  403.   mov DS,AX
  404.   mov BX,wLpt                           ;Portadresse holen
  405.   shl BX,1
  406.   mov DX,DS:[0408h+BX]
  407.   cmp DX,0100h                          ;Schnittstelle vorhanden?
  408.   jb @@Error
  409.   test DX,0003h
  410.   jne @@Error
  411.   mov AL,11110001b                      ;Pull-Up-WiderstÑnde hochziehen
  412.   out DX,AL
  413.   inc DX                                ;Stellung lesen
  414.   in AL,DX
  415.   xor AL,10000000b                      ;Busy wird invertiert
  416.   shr AL,1                              ;Bits an die richtige Stelle schieben
  417.   shr AL,1
  418.   shr AL,1
  419.   xor AH,AH
  420. @@Error:
  421.   pop DS                                ;Ergebnisvariable setzen
  422.   mov L64Result,AX
  423.   ret
  424. L64Joystick2 endp
  425.  
  426. end
  427.